package com.healthcloud.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.healthcloud.entity.*;
import org.apache.shiro.authc.credential.PasswordService;
import org.dozer.Mapper;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.healthcloud.dao.DoctorMapper;
import com.healthcloud.dao.HospDrAssoMapper;
import com.healthcloud.dao.HospitalDepartmentMapper;
import com.healthcloud.dao.HospitalMapper;
import com.healthcloud.service.DoctorService;
import com.healthcloud.service.UserService;
import com.healthcloud.utils.EntityUtils;
import com.healthcloud.utils.PageParam;
import com.healthcloud.vo.DepartmentVo;
import com.healthcloud.vo.DoctorHospitalVo;
import com.healthcloud.vo.HospitalVo;

/**
 * Created by houxianghua on 2015/7/27.
 */
@Service
@Transactional
public class DoctorServiceImpl implements DoctorService {

    @Autowired
    private DoctorMapper doctorMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private HospitalMapper hospitalMapper;

    @Autowired
    private HospDrAssoMapper hospDrAssoMapper;

    @Autowired
    private HospitalDepartmentMapper hospitalDepartmentMapper;

    @Autowired
    private PasswordService passwordService;

    @Autowired
    private Mapper beanMapper;

    @Override
    public Doctor get(Long id) {
        return doctorMapper.get(id);
    }

    @Override
    public List<Doctor> findByEntityAll(Doctor entity) {
        return doctorMapper.findByEntityAll(entity);
    }

    @Override
    public List<Doctor> search(Doctor entity, PageParam pageParam) {
        return doctorMapper.search(entity, pageParam);
    }

    @Override
    public int count(Doctor entity) {
        return doctorMapper.count(entity);
    }

    @Override
    @Transactional
    public void register(SysUserEntity user, Doctor doctor, Long hospId, Long[] officeCodes) {
        SysUserEntity drUser = userService.register(user);
        doctor.setUserId(drUser.getId());
        doctor.setCreatedTime(new Date());
        doctor.setUpdatedTime(new Date());
        doctorMapper.save(doctor);
        for (Long officeCode : officeCodes) {
            HospDrAsso asso = new HospDrAsso();
            asso.setDrId(doctor.getId());
            asso.setHospId(hospId);
            asso.setOfficeCode(officeCode);
            EntityUtils.setDateTime(drUser.getUpdateTime(), asso);
            hospDrAssoMapper.save(asso);
        }
    }

    @Override
    public void register(SysUserEntity user, Doctor doctor, Map<Long, List<Long>> map) {
        Date now = new Date();
        //注册用户基本信息
        SysUserEntity drUser = userService.register(user);
        //新增医生基本信息
        doctor.setUserId(drUser.getId());
        doctor.setCreatedTime(now);
        doctor.setUpdatedTime(now);
        doctorMapper.save(doctor);
        //新增医生，医院，科室的关联信息
        for(Map.Entry<Long, List<Long>> entry:map.entrySet()){
            Long hospId = entry.getKey();//医院id
            List<Long> officeCodes = entry.getValue();//科室id
            for (Long officeCode : officeCodes) {
                HospDrAsso asso = new HospDrAsso();
                asso.setDrId(doctor.getId());
                asso.setHospId(hospId);
                asso.setOfficeCode(officeCode);
                asso.setCreatedTime(now);
                asso.setUpdatedTime(now);
                hospDrAssoMapper.save(asso);
            }
        }
    }

    @Override
    @Transactional
    public void save(Doctor doctor) {
        doctor.setCreatedTime(new Date());
        doctor.setUpdatedTime(new Date());
        doctorMapper.save(doctor);
    }

    @Override
    @Transactional
    public int update(Doctor entity) {
        entity.setUpdatedTime(new Date());
        return doctorMapper.update(entity);
    }

    @Override
    @Transactional
    public void update(SysUserEntity user, Doctor doctor, Map<Long, List<Long>> map) {
        Date now = new Date();
        //注册用户基本信息
        userService.update(user);
        //新增医生基本信息
        doctor.setUserId(user.getId());
        doctor.setUpdatedTime(now);
        if(doctor.getId()==null||doctor.getId().equals("")){
            doctorMapper.save(doctor);
        }else{
            doctorMapper.update(doctor);
        }
        //根据医生id删除医生，医院，科室的关联信息
        hospDrAssoMapper.deleteByDrId(doctor.getId());
        //新增医生，医院，科室的关联信息
        for(Map.Entry<Long, List<Long>> entry:map.entrySet()){
            Long hospId = entry.getKey();//医院id
            List<Long> officeCodes = entry.getValue();//科室id
            for (Long officeCode : officeCodes) {
                HospDrAsso asso = new HospDrAsso();
                asso.setDrId(doctor.getId());
                asso.setHospId(hospId);
                asso.setOfficeCode(officeCode);
                asso.setCreatedTime(now);
                asso.setUpdatedTime(now);
                hospDrAssoMapper.save(asso);
            }
        }
    }

    @Override
    @Transactional
    public int delete(Long id) {
        return doctorMapper.delete(id);
    }

    @Override
    @Transactional
    public int deletes(Long[] ids) {
        int j = 0;
        for (int i = 0; i < ids.length; i++) {
            j = delete(ids[i]);
        }
        return j;
    }

    @Override
    public Doctor getDoctorByUserId(Long userId) {
        return doctorMapper.getDoctorByUserId(userId);
    }

    /**
     * 根据医院id获取医生完整信息列表
     * @param hospId：医院id
     * @return
     * */
    @Override
    public List<DoctorHospitalVo> getDoctorVosByHospId(Long hospId) {
        List<DoctorHospitalVo> doctorHospitalVoList = new ArrayList<>();

        Hospital hospital = hospitalMapper.get(hospId);//获取医院信息

        HospDrAsso hospDrAsso = new HospDrAsso();
        hospDrAsso.setHospId(hospId);
        List<HospDrAsso> hospDrAssoList = hospDrAssoMapper.findByEntityAll(hospDrAsso);//获取医院与医生关联信息

        //设置医生与科室的管理信息到doctorMap中key：医生id，value：医院与科室关联表id集合
        Map<Long,List<Long>> doctorMap =  new HashMap<>();
        for (int i = 0; i <hospDrAssoList.size() ; i++) {
            Long drId = hospDrAssoList.get(i).getDrId();//医生id
            Long officeCode = hospDrAssoList.get(i).getOfficeCode();//医院与科室关联表id
            if(doctorMap.containsKey(drId)){
                doctorMap.get(drId).add(officeCode);
            }else{
                List<Long> officeCodeList = new ArrayList<>();
                officeCodeList.add(officeCode);
                doctorMap.put(drId,officeCodeList);
            }
        }
        for (Long drId : doctorMap.keySet()) {

            DoctorHospitalVo doctorHospitalVo = new DoctorHospitalVo();
            //设置医生信息
            Doctor doctor = doctorMapper.get(drId);
            doctorHospitalVo.setDoctor(doctor);
            //设置用户信息
            SysUserEntity user = userService.get(doctor.getUserId());
            doctorHospitalVo.setUser(user);
            //设置医院、科室信息
            List<HospitalVo> hospitalList = new ArrayList<>();
            HospitalVo hospitalVo =  new HospitalVo();
            hospitalVo.setHospital(hospital);//beanMapper.map(hospital, hospitalVo);//将医院信息赋值到医院展示类中

            List<Long> officeCodeList = doctorMap.get(drId);//医院与科室关联表id的List
            List<DepartmentVo> hdList = new ArrayList<>();//医院与科室关联表List
            for (int i = 0; i < officeCodeList.size(); i++) {
                HospitalDepartment hospitalDepartment = hospitalDepartmentMapper.get(new Long(officeCodeList.get(i)).intValue());
                DepartmentVo departmentVo = new DepartmentVo();
                beanMapper.map(hospitalDepartment, departmentVo);
                hdList.add(departmentVo);
            }

            hospitalVo.setDepartmentList(hdList);
            hospitalList.add(hospitalVo);
            doctorHospitalVo.setHospitalList(hospitalList);
            doctorHospitalVoList.add(doctorHospitalVo);
        }
        return doctorHospitalVoList;
    }

    @Override
    public List<DoctorHospitalVo> getDoctorVosByDrId(Long drId) {
        return null;
    }

    @Override
    public List<DoctorHospitalVo> getDoctorVosByUserId(Long userId) {
        return null;
    }
}
